###############################################################################

#

# Generic Makefile for C/C++ Program

#

# Author: whyglinux (whyglinux AT hotmail DOT com)

# Date:   2006/03/04



# Description:

# The makefile searches in <SRCDIRS> directories for the source files

# with extensions specified in <SOURCE_EXT>, then compiles the sources

# and finally produces the <PROGRAM>, the executable file, by linking

# the objectives.



# Usage:

#   $ make           compile and link the program.

#   $ make objs      compile only (no linking. Rarely used).

#   $ make clean     clean the objectives and dependencies.

#   $ make cleanall  clean the objectives, dependencies and executable.

#   $ make rebuild   rebuild the program. The same as make clean && make all.

#==============================================================================



## Customizing Section: adjust the following if necessary.

##=============================================================================

DIR_SRC=.
DIR_BIN=.
DIR_OBJ=.
DIR_INC=.
DIR_LIB=./lib

# The executable file name.

# It must be specified.

# PROGRAM   := a.out    # the executable name

SRC       := $(wildcard *.cpp)
PROGRAM   := $(patsubst %.cpp, %, $(notdir ${SRC}))



# The directories in which source files reside.

# At least one path should be specified.

# SRCDIRS   := .        # current directory

SRCDIRS   := .


# The source file types (headers excluded).

# At least one type should be specified.

# The valid suffixes are among of .c, .C, .cc, .cpp, .CPP, .c++, .cp, or .cxx.

# SRCEXTS   := .c      # C program

# SRCEXTS   := .cpp    # C++ program

# SRCEXTS   := .c .cpp # C/C++ program

SRCEXTS   := .c .cpp



# The flags used by the cpp (man cpp for more).

# CPPFLAGS  := -Wall -Werror # show all warnings and take them as errors

CPPFLAGS  := -Wall -Werror



# The compiling flags used only for C.

# If it is a C++ program, no need to set these flags.

# If it is a C and C++ merging program, set these flags for the C parts.

CFLAGS    :=

CFLAGS    +=



# The compiling flags used only for C++.

# If it is a C program, no need to set these flags.

# If it is a C and C++ merging program, set these flags for the C++ parts.

CXXFLAGS  :=

CXXFLAGS  += -g


# The directories in which include files reside.

# At least one path should be specified.

# INC   := .        # current directory

my_inc := . ./include /usr/include /usr/local/include
INC    := $(addprefix -I, $(my_inc))


# The directories in which lib files reside.

# At least one path should be specified.

# LIB   := .        # current directory

my_lib   := ./lib /lib /usr/local/lib
LIB   := $(addprefix -L, $(my_lib))



# The library and the link options ( C and C++ common).

my_ldflags = gtest;
LDFLAGS   := $(addprefix -l, $(my_ldflags))

LDFLAGS   +=



## Implict Section: change the following only when necessary.

##=============================================================================

# The C program compiler. Uncomment it to specify yours explicitly.

#CC      = gcc



# The C++ program compiler. Uncomment it to specify yours explicitly.

#CXX     = g++



# Uncomment the 2 lines to compile C programs as C++ ones.

CC      = $(CXX)

CFLAGS  = $(CXXFLAGS)



# The command used to delete file.

#RM        = rm -f



## Stable Section: usually no need to be changed. But you can add more.

##=============================================================================

SHELL   = /bin/sh

SOURCES = $(foreach d,$(SRCDIRS),$(wildcard $(addprefix $(d)/*,$(SRCEXTS))))

OBJS    = $(foreach x,$(SRCEXTS),$(patsubst %$(x),%.o,$(filter %$(x),$(SOURCES))))

DEPS    = $(patsubst %.o,%.d,$(OBJS))



.PHONY : all objs clean cleanall rebuild



all : $(PROGRAM)



# Rules for creating the dependency files (.d).

#---------------------------------------------------

#处理头文件的自动依赖
define generate-deps
	@$(CC) -MM $(CPPFLAGS) $< > $@.$$$$; \
	sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
	rm -f $@.$$$$
endef


%.d : %.c
	$(generate-deps)

%.d : %.C
	$(generate-deps)

%.d : %.cc
	$(generate-deps)

%.d : %.cpp
	$(generate-deps)

%.d : %.CPP
	$(generate-deps)

%.d : %.c++
	$(generate-deps)

%.d : %.cp
	$(generate-deps)

%.d : %.cxx
	$(generate-deps)

# Rules for producing the objects.

#---------------------------------------------------

objs : $(OBJS)


%.o : %.c

	$(CC) -c $(CPPFLAGS) $(CFLAGS) $(INC) $< -o $@



%.o : %.C

	$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $(INC) $< -o $@



%.o : %.cc

	$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $(INC) $< -o $@



%.o : %.cpp
	$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $(INC) $< -o $@

%.o : %.CPP

	$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $(INC) $< -o $@



%.o : %.c++

	$(CXX -c $(CPPFLAGS) $(CXXFLAGS) $(INC) $< -o $@



%.o : %.cp

	$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $(INC) $< -o $@



%.o : %.cxx

	$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $(INC) $< -o $@



# Rules for producing the executable.

#----------------------------------------------

$(PROGRAM) : % : %.o

ifeq ($(strip $(SRCEXTS)), .c)  # C file

	$(CC) -o $@ $< $(LIB) $(LDFLAGS)

else                            # C++ file

	$(CXX) -o $@ $< $(LIB) $(LDFLAGS)

endif



-include $(DEPS)



rebuild: clean all



clean :
	$(RM) *.o *.d

cleanall:clean
	$(RM) $(addsuffix .exe, $(PROGRAM))


### End of the Makefile ##  Suggestions are welcome  ## All rights reserved ###

###############################################################################

